package com.hlb.manager.service;

import com.hlb.entity.Product;
import com.hlb.entity.enums.ProductStatus;
import com.hlb.manager.repositories.ProductRepository;
import org.slf4j.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import javax.persistence.criteria.*;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;


/**
 * @author hanlibin
 * @Description: 产品服务类
 * @date 2018/7/1121:31
 */
@Service
public class ProductService {
    private static Logger log=LoggerFactory.getLogger(ProductService.class);
    @Autowired
    private ProductRepository productRepository;

    public Product addProduct(Product product){
        log.debug("创建产品，参数:{}",product);
        //数据校验
        checkProduct(product);
        //设置默认值
        setDefault(product);
        Product result=productRepository.save(product);
        log.debug("创建产品，结果为:{}",result);
        return result;
    }
    /**
     * 设置默认值
     * 创建时间、更新时间
     * 投资步长、锁定期、状态
     *
     * @param product
     */
    private void setDefault(Product product) {
        if (product.getCreateAt() == null) {
            product.setCreateAt(new Date());
        }
        if (product.getUpdateAt() == null) {
            product.setUpdateAt(new Date());
        }
        if (product.getStepAmount() == null) {
            product.setStepAmount(BigDecimal.ZERO);
        }
        if (product.getLockTerm() == null) {
            product.setLockTerm(0);
        }
        if (product.getStatus() == null) {
            product.setStatus(ProductStatus.AUDITING.name());
        }
    }

    private void checkProduct(Product product) {
        Assert.notNull(product.getId(),"编号不能为空");
        Assert.isTrue(BigDecimal.ZERO.compareTo(product.getRewardRate()) < 0 && BigDecimal.valueOf(30).compareTo(product.getRewardRate()) >= 0, "收益率范围错误");
        Assert.isTrue(BigDecimal.valueOf(product.getStepAmount().longValue()).compareTo(product.getStepAmount()) == 0, "投资步长需为整数");
    }

    /**
     * 获取单个产品
     * @param id 产品id
     * @return 返回对应的产品
     */
    public Product findOne(String id){
        Assert.notNull(id, "需要产品的编号");
        log.debug("查询单个产品，id={}", id);
        Product result = productRepository.getOne(id);
        log.debug("查询单个产品，结果：{}", result);
        return result;
    }


    /**
     * 条件查询
     * @param ids //多个编号查询
     * @param minRewardRate//最小收益率
     * @param maxRewardRate//最大收益率
     * @param statusList//最大收益率多个状态
     * @param pageable//分页
     * @return
     */
    public Page<Product> query(List ids, BigDecimal minRewardRate, BigDecimal maxRewardRate, List<String> statusList, Pageable pageable ){
        log.debug("查询产品,idList={},minRewardRate={},maxRewardRate={},statusList={},pageable={}", ids, minRewardRate, maxRewardRate, statusList, pageable);

        Specification specification=new Specification() {
            @Override
            public Predicate toPredicate(Root root, CriteriaQuery query, CriteriaBuilder criteriaBuilder) {
                Expression<String> idcol=root.get("id");
                Expression<BigDecimal> rewardRatecol=root.get("rewardRate");
                Expression<String> statuscol=root.get("status");
                List<Predicate> predicates=new ArrayList<>();
                if (ids != null && ids.size() > 0) {
                    predicates.add(idcol.in(ids));
                }
                if (minRewardRate != null && BigDecimal.ZERO.compareTo(minRewardRate) < 0) {
                    predicates.add(criteriaBuilder.ge(rewardRatecol, minRewardRate));
                }
                if (maxRewardRate != null && BigDecimal.ZERO.compareTo(maxRewardRate) < 0) {
                    predicates.add(criteriaBuilder.le(rewardRatecol, maxRewardRate));
                }
                if (statusList != null && statusList.size() > 0) {
                    predicates.add(statuscol.in(statusList));
                }
                query.where(predicates.toArray(new Predicate[0]));
                return null;
            }
        };
        Page<Product> result=productRepository.findAll(specification,pageable);
        log.debug("查询产品,结果={}", result);
        return result;
    }
}
